﻿using JigLibX.Collision;
using JigLibX.Geometry;
using JigLibX.Physics;
using Microsoft.Xna.Framework;

namespace Library
{
    public class PhysicsObject :Component, I3DComponent
    {
        float mass = 1;
        public Body Body;
        public CollisionSkin CollisionSkin;

        public float Mass 
        {
            get { return mass; }
            set { mass = value;
            Vector3 com = SetMass(value);
            if (CollisionSkin != null)
                CollisionSkin.ApplyLocalTransform(new JigLibX.Math.Transform(-com, Matrix.Identity));
            }
        }

        public Vector3 Position 
        {
            get { return Body.Position; }
            set { Body.MoveTo(value, Body.Orientation); }
        }

        public Matrix Rotation
        {
            get { return Body.Orientation; }
            set { Body.MoveTo(Body.Position, value); }
        }

        public Vector3 EulRotation
        {
            get { return MathUtils.MatrixToVector3(Rotation); }
            set { Rotation = MathUtils.Vector3ToMatrix(value); }
        }

        public bool Immovable
        {
            get { return Body.Immovable; }
            set { Body.Immovable = value; }
        }

        public BoundingBox BoundingBox
        {
            get 
            {
                if (CollisionSkin != null)
                    return Body.CollisionSkin.WorldBoundingBox;
                else
                    return new BoundingBox(Position - Vector3.One, Position + Vector3.One);
            }
        }

        public Vector3 Scale
        {
            get { return Vector3.One; }
            set {  }
        }

        public Vector3 Velocity
        {
            get { return Body.Velocity; }
            set { Body.Velocity = value; }
        }

        public PhysicsObject() : base() { }
        public PhysicsObject(Screen Parent) : base(Parent) { }

        protected void InitializeBody()
        {
            Body = new Body();
            CollisionSkin = new CollisionSkin(Body);
            Body.CollisionSkin = this.CollisionSkin;
            Body.EnableBody();
        }

        public Vector3 SetMass(float mass) 
        {
            PrimitiveProperties primitiveProperties = new PrimitiveProperties(PrimitiveProperties.MassDistributionEnum.Solid,
                PrimitiveProperties.MassTypeEnum.Density, mass);

            float junk;
            Vector3 com;
            Matrix it, itCom;

            CollisionSkin.GetMassProperties(primitiveProperties, out junk, out com, out it, out itCom);
            Body.BodyInertia = itCom;
            Body.Mass = junk;

            return com;
        }

        public void OffsetModel(Vector3 PositionOffeset, Matrix RotationOffset)
        {
            CollisionSkin.ApplyLocalTransform(new JigLibX.Math.Transform(PositionOffeset, RotationOffset));
        }

        public override void DisableComponent()
        {
            Body.DisableBody();
            base.DisableComponent();
        }
    }
}
